package checkers3d.logic;

import checkers3d.presentation.WindowFileBrowser;
import checkers3d.presentation.GUILabel;
import checkers3d.presentation.GUIPictureBox;
import checkers3d.presentation.GameEngine;
import checkers3d.presentation.IInputObserver;
import checkers3d.presentation.RenderResourceBitmap;
import checkers3d.storage.ScenarioManager;
import java.awt.Color;
import java.awt.Point;
import java.util.StringTokenizer;

/**
 * Shows a list of scenarios and allows the player to view a preview for it and
 * to play it.
 *
 * @author Ruben Acuna
 */
public class MenuScenarioSelect extends WindowFileBrowser
{
    /**
     * File extension type for this window file browser.
     */

    // Static so that the constructor can see it...
    static private final String FILE_EXTENSION = ".xml";

    /**
     * Maximum number of description lines.
     */
    private final int PREVIEW_LINES = 4;

    /**
     * The position of the text preview.
     */
    private final Point PREVIEW_LINES_POSITION = new Point(GameEngine.WINDOW_SIZE.x - 400 - GameEngine.WINDOW_SIZE.x / 8, 350);

    /**
     * The position of the image preview.
     */
    private final Point PREVIEW_IMAGE_POSITION = new Point(GameEngine.WINDOW_SIZE.x - 400 - GameEngine.WINDOW_SIZE.x / 8, 50);

    /**
     * Number of characters in a line of the description.
     */
    private final int CHARACTER_WRAP = 70;

    /**
     * GUILabel components for the text preview.
     */
    private GUILabel[] previewLabels = new GUILabel[PREVIEW_LINES];

    /**
     * GUIPictureBox component for the image preview.
     */
    private GUIPictureBox previewPicture = new GUIPictureBox((RenderResourceBitmap)null, PREVIEW_IMAGE_POSITION);

    /**
     * Class constructor that requires the window size. It creates control
     * buttons, scenario list, current scenario preview. If scenarios are
     * available, the first one is auto-previewed.
     *
     * @param size Size of window.
     */
    public MenuScenarioSelect(Point size)
    {
        super("Scenarios", ScenarioManager.LOCATION_SCENARIOS, FILE_EXTENSION, size);

        setStartObserver(new ObserverLogin(this));
        
        //add preview components for the currently selected scenario.
        add(previewPicture);
        Point lastLinePosition = PREVIEW_LINES_POSITION;
        for(int i = 0; i < PREVIEW_LINES; i++)
        {
            previewLabels[i] = new GUILabel("", Color.WHITE, (Point)lastLinePosition.clone());
            add(previewLabels[i]);
            lastLinePosition.translate(0, previewLabels[i].getRenderResource().getHeight() + TEXT_PAD);
        }

        if(availableFilenameLabels.size() > 0 )
            selectFile(availableFilenameLabels.getFirst().getText());
    }

    /**
     * Selects a scenario by making its label yellow and showing a preview image
     * and desciption.
     *
     * @param name Scenario name.
     */
    @Override
    protected void selectFile(String name)
    {
        super.selectFile(name);

        RenderResourceBitmap image = ScenarioManager.getScenarioRR(name);
        String text = ScenarioManager.getScenarioFact(name, "description");
        StringTokenizer textTokenizer = new StringTokenizer(text, " ");

        //set the preview picture
        previewPicture.setRenderResource(image);

        //set the preview text. the text is wrapped at 45 characters.
        for(int i = 0; i < PREVIEW_LINES; i++)
        {
            String line = new String();

            if(textTokenizer.hasMoreTokens())
                line = textTokenizer.nextToken();

            while(textTokenizer.hasMoreTokens() && line.length() < CHARACTER_WRAP)
                line = line + " " + textTokenizer.nextToken();

            previewLabels[i].setText(line);
        }
    }

    /**
     * Returns a string representation of this object containing it's class name.
     *
     * @return String representation.
     */
    @Override
    public String toString()
    {
        return getClass().getName();
    }
    
    /**
     * A observer for a button displays the player login window.
     */
    private class ObserverLogin implements IInputObserver
    {
        /**
         * Reference to the parent MenuScenarioSelect object, use for finding
         * the current scenario name.
         */
        private MenuScenarioSelect parent;

        /**
         * Class constructor that keeps a reference to the parent object.
         *
         * @param parent Reference to the parent MenuScenarioSelect object.
         */
        public ObserverLogin(MenuScenarioSelect parent)
        {
            this.parent = parent;
        }

        /**
         * Displays the player login window.
         *
         * @param position Location of click within button.
         */
        public void onClick(Point position)
        {
            GameMaster.getInstance().addGUIContainer(new MenuScenarioLoginMP(parent.getSize(), parent.getSelectedFilename()));
        }

         /**
         * Key press observer that does nothing.
         *
         * @param key Key that was pressed.
         */
        public void onKeyPress(char key)
        {
            //do nothing.
        }
    }
}